汉诺塔(Hanoi Tower),又称河内塔,源于印度一个古老传说。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺

import java.awt.*;
import java.awt.event.*;
public class hanota extends Frame implements ActionListener,TextListener,ItemListener //定义新的窗口类
{ static int n=1;                //初始化盘子的个数
    static int timect=19;       //演示的时间设置为中等
    static int ah=550;         //原柱,中间柱,目的柱的高度
    static int bh=550;        
    static int ch=550;       
    static hanota frm=new hanota();    //创建窗口对象
 static Label lab1=new Label("请输入盘子个数(1~10)"); 
 static TextField txt1=new TextField(2);  //创建取得用户定义的盘子个数的文本区
 static Label lab2=new Label("演示速度");
 static Checkbox ckb1=new Checkbox("快");       //用户对演示的时间设置所使用的单选框
 static Checkbox ckb2=new Checkbox("中");
 static Checkbox ckb3=new Checkbox("慢");
 static Button btn1=new Button("演示");   //创建按钮
 static Button btn2=new Button("退出");
 static Button btn3=new Button("刷新");
 static Label lab[]=new Label[10];    //使用标签对象做盘子,最多10个盘
  
 public static void main(String args[])   
 { CheckboxGroup grp=new CheckboxGroup();  //创建单选框组
  btn1.addActionListener(frm);    //设置按钮的事件监听者为FRM
  btn2.addActionListener(frm);
  btn3.addActionListener(frm);
  txt1.addTextListener(frm);     //设置文本的事件监听者为FRM
  ckb1.setCheckboxGroup(grp);     //设置单选框的组grp
  ckb2.setCheckboxGroup(grp);
  ckb3.setCheckboxGroup(grp);
  ckb1.addItemListener(frm);     //设置单选框的事件监听者为FRM    
  ckb2.addItemListener(frm);
  ckb3.addItemListener(frm);
  frm.setResizable(false);     //设置窗口不可改变大小
  frm.setLayout(null);
  frm.setTitle("汉诺塔问题的直观演示");
  frm.setSize(800,600);
  frm.setBackground(Color.pink);
  lab1.setBounds(20,560,150,15);    //初始所有标签,按钮,文本框,单选框的位置
  txt1.setBounds(170,560,20,15);
  lab2.setBounds(20,580,60,15);
  ckb1.setBounds(90,580,30,15);
  ckb2.setBounds(120,580,30,15);
  ckb3.setBounds(150,580,30,15);
  btn1.setBounds(340,560,120,30);
  btn2.setBounds(600,560,120,30);
  btn3.setBounds(340,560,120,30);
  frm.add(txt1);        //加载标签,按钮,文本框,单选框到窗口
  frm.add(lab1);
  frm.add(lab2);
  frm.add(btn1);
  frm.add(btn2);
  frm.add(btn3);
  frm.add(ckb1);
  frm.add(ckb2);
  frm.add(ckb3);
  frm.setVisible(true);      //设置各组件对象是否可见
  btn1.setVisible(false);
  btn3.setVisible(false);
  frm.addWindowListener(new WindowAdapter()  //设置窗口关闭按钮是可用
  {public void windowClosing(WindowEvent e)
     {System.exit(0);
     }
  });
 }
 
 public void paint(Graphics g)     //绘制各个塔柱的位置
 { g.drawLine(20,550,260,550);
  g.drawLine(140,50,140,550);
  g.drawLine(280,550,520,550);
  g.drawLine(400,50,400,550);
  g.drawLine(540,550,780,550);
  g.drawLine(660,50,660,550);
 }
 
 public void actionPerformed(ActionEvent e)      //设置按钮事件
 { Button btn=(Button) e.getSource();
  if(btn==btn1)     //btn1为演示开始按钮
  { 
      for(int i=0;i<=n-1;i++)    //建立盘子对象并加载到窗口
   { lab[i]=new Label();
     lab[i].setSize(24*(i+1),50);
     lab[i].setLocation(140-lab[i].getWidth()/2,550-lab[i].getHeight()*(n-i));
     lab[i].setBackground(Color.red);
     frm.add(lab[i]);
   }
   btn1.setVisible(false);
   for(double i=1;i<=Math.pow(10,6);i++);
     frm.hanoi(lab,n,140,400,660);    //汉诺塔演示的核心程序的调用
   btn3.setVisible(true);   //演示结束显示刷新按钮
   txt1.setVisible(false);   
  }
  if(btn==btn3)      //刷新,回到初始状态
  {  btn3.setVisible(false);
     btn1.setVisible(true);
     for(int i=0;i<=n-1;i++)
         frm.remove(lab[i]);
     txt1.setVisible(true);
             ah=550-50*n;
         bh=550;
               ch=550;
  }
  if(btn==btn2)     //退出
    System.exit(0);
 }
 public void textValueChanged(TextEvent e)    //的到用户指定的盘子的个数
 { TextField txt=(TextField) e.getSource();
    if(txt==txt1)
    { try{n=Integer.parseInt(txt1.getText());}   //对输入的异常处理
       catch(NumberFormatException f){btn1.setVisible(false);
           return;} 
        if(n>0&&n<=10)   //对输入的异常处理
        { ah=550-50*n;
        btn1.setVisible(true);
     }else
  btn1.setVisible(false);      
     }
 }
 
 
 public void itemStateChanged(ItemEvent e)   //用户设置演示中盘子移动快慢
 {if(ckb1.getState()==true)
  timect=18;
  if(ckb2.getState()==true)
   timect=19;
   if(ckb3.getState()==true)
    timect=20;
 }
 
 public void settimectr(int timectc)   //移动的间隔时间
 {for(double h=1;h<=Math.pow(2,(double)timectc);h++);{
			Graphics m;
			m = this.getGraphics();
			m.setColor(Color.BLACK);
			paint(m);
		} 
               
  }
 
 public void setactcolor(Label labl[],int ncl)  //盘子移动时的颜色,绿色
 {labl[ncl-1].setBackground(Color.green);
 }
 public void setcolorbak(Label labl[],int ncl) //盘子静止时的颜色,红色
 {labl[ncl-1].setBackground(Color.black);
 }

 
 
 public void hanoi(Label labc[],int nc,int xc,int yc,int zc)  //递归实现
 { if(nc==1)
  {setactcolor(labc,1);
    settimectr(timect);  
    move(labc,xc,1,zc);   //当只有一个盘子时直接从原柱移动到目的柱
    
    settimectr(timect);
    setcolorbak(labc,1);
  }
  else{       
   hanoi(labc,nc-1,xc,zc,yc);//当有N个盘子时,先把上面N-1个盘子移动到辅助的柱子上
   setactcolor(labc,nc);
   settimectr(timect);
   move(labc,xc,nc,zc);  //移动第N个盘子到目的柱
   
   settimectr(timect);
   setcolorbak(labc,nc);
      hanoi(labc,nc-1,yc,xc,zc);//把剩下的N-1个盘子从辅助的柱子移动到目的柱
   }
 }
 
 public void move(Label labb[],int xb,int nb,int zb)  //移动操作方法
 { if(xb==140&&zb==660)
   {labb[nb-1].setLocation(660-labb[nb-1].getWidth()/2,ch-50);
   ah=ah+50;
   ch=ch-50;
   }
   if(xb==140&&zb==400)
   {labb[nb-1].setLocation(400-labb[nb-1].getWidth()/2,bh-50);
   ah=ah+50;
   bh=bh-50;
   }
   if(xb==400&&zb==660)
   {labb[nb-1].setLocation(660-labb[nb-1].getWidth()/2,ch-50);
   bh=bh+50;
   ch=ch-50;
   }
   if(xb==400&&zb==140)
   {labb[nb-1].setLocation(140-labb[nb-1].getWidth()/2,ah-50);
   ah=ah-50;
   }
   if(xb==660&&zb==400)
   {labb[nb-1].setLocation(400-labb[nb-1].getWidth()/2,bh-50);
   ch=ch+50;
   bh=bh-50;
   }
    if(xb==660&&zb==140)
   {labb[nb-1].setLocation(140-labb[nb-1].getWidth()/2,ah-50);
   ch=ch+50;
   ah=ah-50;
   }
 }
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这段英文描述的是汉诺塔问题,它是一个经典的问题。汉诺塔Hanoi Tower又称河内塔源于印度一个古老传说大梵天创造世界时造了三根金刚石柱子,在一根柱子上从下往上按大小顺序放着64黄金圆盘大梵天命令婆罗门圆盘下面开始按大小顺序依次移到另一根柱子上,且过程中小圆盘必须在大圆盘上面,不允许大圆盘压在小圆盘上面。完成这项任务所需的步数是2的64次方减1,约等于18.4亿步,如果每秒钟完成一步,需要585年左右。 ### 回答2: 婆将这些圆盘一根柱子上全部移到另一根柱子上,并且规定只能借助第三根柱子。根据传说,当婆婆完成这个任务时,世界就将结束。这个问题看似简单,但是实际上需要一定的推理和图形思维。解决这个问题的难点在于如何将大盘从一根柱子移到另一根柱子,并且保证每个圆盘大小关系不变,即大盘不能压在小盘上面。最简单的方法就是逐个移动,但是这需要大量的次数和时间。数学家提出的递归思想则更加高效,将问题化简为递归子问题进行解决。在汉诺塔问题中,每个盘子都可以看一个节点,将问题转化为移动一个子问题,然后再移动根节点,最后再将子问题移动回去。这样,每次只需移动一个盘子,且规律逐渐显现出来,即移动n个盘子的方法可以转化为移动n-1个盘子+移动根节点+移动n-1个盘子的方法,从而避免了重复计算和无限递归。因此,汉诺塔问题不仅锻炼了我们的思维逻辑和数学能力,还展示了递归方法在计算中的实际应用。 ### 回答3: 罗门把这些盘子从下面开始按照大小顺序移到另外一根柱子上。 汉诺塔问题是指有三根柱子和一堆不同大小的盘子,盘子从下往上按照逐渐变大的顺序摆放在一根柱子上。游戏的目标是把所有盘子都移动到另一根柱子上,每次只能移动一个盘子,且大盘子不能放在小盘子之上。 这个经典问题涉及到递归、分治和数学方面的知识。在解决汉诺塔问题时,使用递归可以简化问题,并找到一种通用的解决方法。通过分治思想,将复杂问题分解成小问题来解决,使得问题变得更加容易处理。 在计算汉诺塔问题中,我们可以使用数学公式来计算出移动盘子的最小步骤数。对于一个汉诺塔问题,最少的步骤数可以计算为2的n次方减一,其中n为盘子的数量。 汉诺塔问题是一个非常有趣的问题,它不仅可以用来锻炼我们的思维能力,还能帮助我们理解递归和分治思想,同时也为我们提供了一个优秀的数学智力游戏。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值